#include <vector>
#include <numeric>
#include <algorithm>
#include <cctype>
#include <time.h>
#include "scorer.h"
using namespace std;

namespace scorer {
  
  // Function returns array of results containing the key of the result and the matched score of the result
  QList<ResultItem> score(vector<string> list, string match, bool ignoreExt) {
    QList<ResultItem> results;
    for (int i=0; i<(int)list.size(); i++) {
      string filename = list[i];
      // only match file name, not path
      filename = filename.substr(filename.find_last_of("/")+1);
      // Remove extension if it should be ignored
      if (ignoreExt) filename = filename.substr(0, filename.find_last_of("."));
      int itemScore = match == "" ? 0 : scoreMatch(filename, match);
      if (itemScore == -1) {
        continue; // no match, skip
      }
      
      ResultItem temp(filename);
      temp.path = list[i];
      temp.score = itemScore;
      results.append(temp);
    }
    return results;
  }

  int scoreMatch(string name, string match) {
    transform(name.begin(), name.end(), name.begin(), ::tolower);
    transform(match.begin(), match.end(), match.begin(), ::tolower);
    // Set up vector of indices of matched characters
    vector<int> indices(0);
    int pos = 0;
    for (int i=0; i<(int)match.length(); i++) {
      pos = name.find_first_of(match[i], pos);
      if (pos == -1) { // no match
        return -1;
      }
      indices.push_back(pos);
      pos++;
    }
    
    
    int frags = 0;
    int midLen = 0;
    int end = name.length()-1 - indices.back();
    
    for (int i=1; i<(int)indices.size(); i++) {
      int gap = indices[i]-indices[i-1]-1;
      if (gap != 0) {
        frags++;
        midLen += gap;
      }
    }
    
    QSettings settings;
    int begHigh = settings.value("begHigh").toInt();
    int midBonus = settings.value("midBonus").toInt();
    int endHigh = settings.value("endHigh").toInt();
    int fragPen = settings.value("fragPen").toInt();
    
    int point = begHigh/(indices[0]+1) + // First part
                midBonus*(int)indices.size() + // Middle matches
                endHigh/(end+1) - // End part
                fragPen*frags*((name.length()-1)/2); // Fragmentation penalty
    if (point < 0) point = 0;
    return point;
  }
  
}
